package com.yuews.codegenerator.parser;

import com.yuews.codegenerator.model.ColumnInfo;
import com.yuews.codegenerator.model.TableInfo;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据库解析器 - 通过直接连接数据库获取表信息
 */
public class DatabaseParser implements TableInfoParser {

    @Override
    public String getParserType() {
        return "database";
    }

    @Override
    public List<TableInfo> parse(String source) {
        List<TableInfo> tables = new ArrayList<>();
        Connection conn = null;

        try {
            // source格式: "jdbc:mysql://host:port/dbname,username,password[,table1,table2,...]"
            String[] connInfo = source.split(",");
            if (connInfo.length < 3) {
                throw new IllegalArgumentException("数据库连接信息格式错误: jdbc:mysql://host:port/dbname,username,password[,table1,table2,...]");
            }

            String url = connInfo[0];
            String username = connInfo[1];
            String password = connInfo[2];

            // 获取可选的表名列表（如果指定了的话）
            String[] specifiedTables = null;
            if (connInfo.length > 3) {
                specifiedTables = new String[connInfo.length - 3];
                System.arraycopy(connInfo, 3, specifiedTables, 0, connInfo.length - 3);
            }

            // 根据URL判断数据库类型并加载驱动
            if (url.contains("mysql")) {
                Class.forName("com.mysql.cj.jdbc.Driver");
            } else if (url.contains("oracle")) {
                Class.forName("oracle.jdbc.OracleDriver");
            } else if (url.contains("postgresql")) {
                Class.forName("org.postgresql.Driver");
            } else if (url.contains("sqlserver")) {
                Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            }

            // 建立连接
            conn = DriverManager.getConnection(url, username, password);
            DatabaseMetaData metaData = conn.getMetaData();

            // 获取数据库名称
            String databaseName = extractDatabaseName(url);

            // 确定要查询的表名模式
            String tableNamePattern = "%";
            if (specifiedTables != null && specifiedTables.length > 0) {
                // 如果指定了表名，使用第一个表名进行查询
                // 注意：对于多个表，我们将在后面的代码中处理
                tableNamePattern = specifiedTables[0];
            }

            ResultSet tablesResultSet = metaData.getTables(databaseName, null, tableNamePattern, new String[]{"TABLE"});

            List<String> tablesToProcess = new ArrayList<>();
            if (specifiedTables != null && specifiedTables.length > 0) {
                // 如果指定了表名列表，直接使用
                for (String table : specifiedTables) {
                    tablesToProcess.add(table);
                }
            } else {
                // 否则获取所有表
                while (tablesResultSet.next()) {
                    tablesToProcess.add(tablesResultSet.getString("TABLE_NAME"));
                }
            }
            // 处理每个表
            for (String tableName : tablesToProcess) {
                // 重新查询该表的详细信息
                ResultSet singleTableResultSet = metaData.getTables(databaseName, null, tableName, new String[]{"TABLE"});
                String tableComment = "";
                if (singleTableResultSet.next()) {
                    tableComment = singleTableResultSet.getString("REMARKS");
                }
                singleTableResultSet.close();

                TableInfo tableInfo = new TableInfo();
                tableInfo.setTableName(tableName);
                tableInfo.setTableComment(tableComment);

                // 获取表的列信息
                ResultSet columnsResultSet = metaData.getColumns(databaseName, null, tableName, "%");
                List<ColumnInfo> columns = new ArrayList<>();

                while (columnsResultSet.next()) {
                    ColumnInfo column = new ColumnInfo();
                    column.setColumnName(columnsResultSet.getString("COLUMN_NAME"));
                    column.setDataType(columnsResultSet.getString("TYPE_NAME"));
                    // 先使用标准JDBC方式获取注释
                    column.setColumnComment(columnsResultSet.getString("REMARKS"));
                    column.setLength(columnsResultSet.getInt("COLUMN_SIZE"));
                    column.setNotNull("NO".equals(columnsResultSet.getString("IS_NULLABLE")));
                    column.setDefaultValue(columnsResultSet.getString("COLUMN_DEF"));

                    columns.add(column);
                }
                columnsResultSet.close();

                // 对于Oracle数据库，使用特殊查询获取列注释
                if (url.contains("oracle")) {
                    // 获取Oracle用户名（通常是连接字符串中的用户名）
                    String schema = username.toUpperCase();
                    String tableNameUpper = tableName.toUpperCase();

                    try (java.sql.Statement stmt = conn.createStatement()) {
                        String sql = "SELECT COLUMN_NAME, COMMENTS FROM USER_COL_COMMENTS WHERE TABLE_NAME = ?";
                        try (java.sql.PreparedStatement pstmt = conn.prepareStatement(sql)) {
                            pstmt.setString(1, tableNameUpper);
                            try (ResultSet rs = pstmt.executeQuery()) {
                                while (rs.next()) {
                                    String colName = rs.getString("COLUMN_NAME");
                                    String comments = rs.getString("COMMENTS");

                                    // 查找对应的列并更新注释
                                    for (ColumnInfo column : columns) {
                                        if (column.getColumnName().equalsIgnoreCase(colName)) {
                                            if (comments != null && !comments.trim().isEmpty()) {
                                                column.setColumnComment(comments);
                                            }
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        // 如果查询失败，记录日志但不抛出异常，继续使用标准方式获取的注释
                        System.err.println("Oracle列注释查询失败，将使用默认注释: " + e.getMessage());
                    }
                }

                // 将列添加到表信息中
                for (ColumnInfo column : columns) {
                    tableInfo.addColumn(column);
                }

                // 获取主键信息
                ResultSet pkResultSet = metaData.getPrimaryKeys(databaseName, null, tableName);
                while (pkResultSet.next()) {
                    String primaryKey = pkResultSet.getString("COLUMN_NAME");
                    tableInfo.setPrimaryKey(primaryKey);
                    // 更新字段的主键标识
                    for (ColumnInfo column : tableInfo.getColumns()) {
                        if (column.getColumnName().equals(primaryKey)) {
                            column.setPrimaryKey(true);
                            break;
                        }
                    }
                }
                pkResultSet.close();

                tables.add(tableInfo);
            }

            // 关闭结果集
            if (specifiedTables == null || specifiedTables.length == 0) {
                tablesResultSet.close();
            }

        } catch (Exception e) {
            throw new RuntimeException("数据库解析失败: " + e.getMessage(), e);
        } finally {
            if (conn != null) {
                try { conn.close(); } catch (Exception e) {}
            }
        }

        return tables;
    }

    /**
     * 从JDBC URL中提取数据库名称
     */
    private String extractDatabaseName(String url) {
        if (url.contains("mysql")) {
            // MySQL URL格式: jdbc:mysql://host:port/dbname
            int lastSlashIndex = url.lastIndexOf('/');
            int questionMarkIndex = url.lastIndexOf('?');
            if (questionMarkIndex > lastSlashIndex) {
                return url.substring(lastSlashIndex + 1, questionMarkIndex);
            } else {
                return url.substring(lastSlashIndex + 1);
            }
        } else if (url.contains("oracle")) {
            // Oracle URL格式: jdbc:oracle:thin:@host:port:sid
            // 对于Oracle，schema通常为用户名
            return "";
        } else if (url.contains("postgresql")) {
            // PostgreSQL URL格式: jdbc:postgresql://host:port/dbname
            int lastSlashIndex = url.lastIndexOf('/');
            int questionMarkIndex = url.lastIndexOf('?');
            if (questionMarkIndex > lastSlashIndex) {
                return url.substring(lastSlashIndex + 1, questionMarkIndex);
            } else {
                return url.substring(lastSlashIndex + 1);
            }
        } else if (url.contains("sqlserver")) {
            // SQL Server URL格式: jdbc:sqlserver://host:port;databaseName=dbname
            int dbNameIndex = url.indexOf("databaseName=");
            if (dbNameIndex > 0) {
                int endIndex = url.indexOf(';', dbNameIndex);
                if (endIndex > 0) {
                    return url.substring(dbNameIndex + 13, endIndex);
                } else {
                    return url.substring(dbNameIndex + 13);
                }
            }
        }
        return "";
    }
}
